<template>
  <div class="Amap">
    <!--搜索框-->
    <div class="pb10">
      <el-row>
        <el-col :span="10">
          <el-input id="tipinput"
                    v-model="searchVal"></el-input>
        </el-col>
        <el-col :span="4"
                class="pl10">
          <el-button type="primary"
                     @click="searchHandle">查询地址</el-button>
        </el-col>
      </el-row>
    </div>
    <div class="map">
      <div id="mapContainer"></div>
      <div id="panel"></div>
    </div>
    <div class="btns">
      <button class="btn"
              @click="drawPolygon">绘制区域</button>
      <button class="btn"
              @click="cleartMouse">清除绘制</button>
      <button class="btn"
              @click="editPolygon">编辑区域</button>
      <button class="btn"
              @click="closePolyEdit">结束编辑</button>
    </div>
  </div>
</template>

<script>
/**
  高德地图
  API https://lbs.amap.com/api/javascript-api/reference/plugin#AMap.MouseTool
  栗子 https://lbs.amap.com/api/javascript-api/example/overlayers/polygon-draw-and-edit
 **/
export default {
  props: {
    position: {
      type: Array,
      required: true
    },
    point: {
      type: Array,
      required: true
    },
    address: {
      type: String,
      required: true
    }
  },
  data () {
    return {
      flg: true,
      searchVal: '', // 搜索词
      polyEditor: null, // 编辑多边形
      mouseTool: null, // 绘制多边形实例
      placeSearch: null, // 搜索实例
      auto: null, // 搜索提示实例
      map: null, // 地图实例
      polygon: null,
      address1: '', // 标记点地址
      path: [],
      location: [],
      isPath: false, // 是否传入多边形经纬度
      isLocation: false // 是否传入坐标点
    }
  },
  created () {
    this.path =
      this.position.length > 0
        ? [...JSON.parse(JSON.stringify(this.position))]
        : []
    this.location =
      this.point.length > 0 ? [...JSON.parse(JSON.stringify(this.point))] : []
    this.address1 = this.address
  },
  mounted () {
    this.AmapLoad().then(
      AMap => {
        // 初始化地图
        this.map = new AMap.Map('mapContainer', {
          zoom: 11
        })
        // 初始化坐标点
        if (this.location.length < 2) {
          this.address = '请在地图上点击训练场所在位置!!!'
          this.location[0] = 113.326135
          this.location[1] = 23.147143
        }
        this.marker = new AMap.Marker({
          map: this.map,
          title: '',
          position: new AMap.LngLat(this.location[0], this.location[1]),
          clickable: true
        })
        this.marker.setLabel({
          content: `<div class="address" style="padding:5px;font-size:14px;">地址：${this.address}</div>`, // 设置文本标注内容
          offset: new AMap.Pixel(-40, -40), // 设置文本标注偏移量
          direction: 'top' // 设置文本标注方位
        })
        this.marker.setMap(this.map)
        // 坐标点设置为地图中心
        this.map.setCenter([this.location[0], this.location[1]]) // 设置初始坐标为地图中心点
        this.map.setZoom(16)
        // 设置搜索
        AMap.service(['AMap.PlaceSearch'], () => {
          // 构造地点查询类
          this.placeSearch = new AMap.PlaceSearch({
            pageSize: 5, // 单页显示结果条数
            pageIndex: 1, // 页码
            map: this.map, // 展现结果的地图实例
            panel: 'panel', // 结果列表将在此容器中进行展示。
            autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
          })
          // 构造搜索下拉提示列表

          this.auto = new AMap.Autocomplete({
            input: 'tipinput'
          })
          // 监听搜索下拉选择
          AMap.event.addListener(this.auto, 'select', this.searchSelectHandle)
          // 点击marker点击
          AMap.event.addListener(this.placeSearch, 'markerClick', this.markerClickHandle)
        })
        // 地图点击时,获取点击地经纬
        let that = this
        this.map.on('click', e => {
          if (!that.flg) {
            return
          }
          let lnglat = e.lnglat
          var geocoder
          if (!geocoder) {
            geocoder = new AMap.Geocoder()
          }
          that.marker.setPosition(lnglat) // 设置标记的位置
          var address
          geocoder.getAddress(lnglat, (status, result) => {
            if (status === 'complete' && result.regeocode) {
              address = result.regeocode.formattedAddress
              that.newAddress = address
              that.marker.setLabel({
                content: `<div class="address" style="padding:5px;font-size:14px;">地址：${address}</div>`, // 设置文本标注内容
                offset: new AMap.Pixel(-40, -40), // 设置文本标注偏移量
                direction: 'top' // 设置文本标注方位
              })
            }
          })
          that.marker.setMap(that.map) // 在地图上显示一个标记;
          that.marker.on('lclick', that.markerClick(that.newAddress, lnglat))
        })
        // 多边形绘制实例
        this.mouseTool = new AMap.MouseTool(this.map)
        this.mouseTool.on('draw', event => {
          // 获取实例地址坐标
          let paths = this.map.getAllOverlays('polygon')[0].getPath()
          paths = paths.map(item => {
            return [item.lng, item.lat]
          })
          this.path = paths
          this.getPosition()
          // 关闭绘制并保存实例
          this.mouseTool.close()
          this.$message('区域绘制完成')
        })
        // 初始化多边形
        if (this.position.length > 0) {
          this.polygon = new AMap.Polygon({
            map: this.map,
            strokeColor: '#FF33FF',
            strokeWeight: 6,
            strokeOpacity: 0.2,
            fillColor: '#1791fc',
            fillOpacity: 0.4,
            strokeStyle: 'solid',
            path: JSON.parse(JSON.stringify(this.path))
          })
        }
      },
      e => {
        console.log('地图加载失败', e)
      }
    )
  },
  destroyed () {
    this.path = []
    this.location = []
  },
  methods: {
    // 点击marker
    markerClickHandle (event) {
      this.$confirm('确定添加此坐标为地址吗？', '确认定位')
        .then(() => {
          this.address1 = event.data.cityname + event.data.address
          this.location = [event.data.location.lng, event.data.location.lat]
          this.getPosition() // 点击坐标传值
        })
        .catch(() => { })
    },
    markerClick (newAddress, lnglat) {
      // this.$confirm("确定添加此坐标为地址吗？", "确认定位").then(() => {
      this.address1 = newAddress
      this.location = [lnglat.lng, lnglat.lat]
      this.getPosition() // 点击坐标传值
      // });
    },
    // 清除图形
    cleartMouse () {
      this.closePolyEdit() // 如果正在编辑，先关闭编辑
      if (this.polygon) {
        // 有默认值先关闭默认多边形
        this.polygon.setMap(null)
      }
      this.mouseTool.close(true)
      this.polyEditor = null
      this.path = []
      this.getPosition() // 获取坐标传给组件
    },
    // 绘制多边形
    drawPolygon () {
      this.flg = false
      if (this.mouseTool && !this.map.getAllOverlays('polygon')[0]) {
        this.mouseTool.polygon({
          strokeColor: '#FF33FF',
          strokeWeight: 6,
          strokeOpacity: 0.2,
          fillColor: '#1791fc',
          fillOpacity: 0.4,
          strokeStyle: 'solid'
        })
      } else {
        this.$message('不能绘制多个图形')
      }
    },
    // 结束编辑多边形
    closePolyEdit () {
      if (this.polyEditor) {
        this.polyEditor.close()
      }
      this.flg = true
      this.getPosition()
    },
    // 编辑多边形
    editPolygon () {
      if (this.map.getAllOverlays('polygon')[0]) {
        this.polyEditor = new window.AMap.PolyEditor(
          this.map,
          this.map.getAllOverlays('polygon')[0]
        )
        this.polyEditor.open()
        this.polyEditor.on('addnode', event => {
          this.endHandle(event)
          // log.info('触发事件：addnode')
        })
        this.polyEditor.on('adjust', event => {
          this.endHandle(event)
          // log.info('触发事件：adjust')
        })
        this.polyEditor.on('removenode', event => {
          this.endHandle(event)
          // log.info('触发事件：removenode')
        })
        this.polyEditor.on('end', event => {
          this.endHandle(event)
          // event.target 即为编辑后的多边形对象
        })
      } else {
        this.$message('请先绘制')
      }
    },
    // 搜索地址
    searchHandle () {
      this.placeSearch.search(this.searchVal)
    },
    // 监听下拉选择
    searchSelectHandle (e) {
      this.placeSearch.setCity(e.poi.adcode)
      this.placeSearch.search(e.poi.name)
      this.searchVal = e.poi.name
    },
    endHandle (e) {
      let path = [...e.target.getPath()]
      path = path.map(item => {
        return [item.lng, item.lat]
      })
      this.path = path
      this.getPosition()
    },
    // 获取坐标
    getPosition () {
      let obj = {
        location: this.location, // 点
        address: this.address1, // 地址
        path: this.path // 多边形
      }
      console.log(obj)
      this.$emit('mapPosition', obj)
    }
  }
}
</script>

<style scoped rel="stylesheet/scss" type="text/scss" lang="scss">
.Amap {
  position: relative;
  .btns {
    position: absolute;
    right: 10px;
    bottom: 5px;
    background: #ffffff;
    .btn {
      padding: 5px 10px;
      background: none;
    }
  }
}
.map {
  #mapContainer {
    width: 100%;
    height: 400px;
  }
  position: relative;
  #panel {
    position: absolute;
    background-color: white;
    max-height: 85%;
    overflow-y: auto;
    top: 10px;
    right: 10px;
    width: 280px;
  }
}
</style>
<style rel="stylesheet/scss" type="text/scss" lang="scss">
.Amap {
  .amap-marker-label {
    border: 1px solid #ccc;
    border-radius: 2px;
  }
}
</style>
